using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using AleaClasses;
using EnablementManager;

namespace AleaDesigner
{
	/// <summary>
	/// Summary description for TfrmNodes.
	/// </summary>
	public class TfrmNodes : TfrmBaseform
	{
		private System.Windows.Forms.ColumnHeader lblLabel;
		private System.Windows.Forms.Panel pnlLabel;
		private System.Windows.Forms.Label label1;
		private System.Windows.Forms.Label label2;
		private System.Windows.Forms.Label label3;
		private System.Windows.Forms.TextBox edDisplayName;
		private System.Windows.Forms.TextBox edDescription;
		private System.Windows.Forms.Label label4;
		private System.Windows.Forms.Button btnBrowseFileName;
		private System.Windows.Forms.OpenFileDialog odFileName;
		private System.Windows.Forms.TextBox edFileName;
		private System.Windows.Forms.ColumnHeader columnHeader1;
		private System.Windows.Forms.Splitter splitter1;
		private System.Windows.Forms.ListView lvNodes;
		private System.Windows.Forms.Label lblNodeCode;
		private System.Windows.Forms.Panel panel1;
		private System.Windows.Forms.Splitter splitter2;
		private System.Windows.Forms.Panel panel2;
		private System.Windows.Forms.Label label8;
		private System.Windows.Forms.Label label9;
		private System.Windows.Forms.ComboBox cbToNode;
		private System.Windows.Forms.ComboBox cbLabel;
		private System.Windows.Forms.ListView lvEdges;
		private System.Windows.Forms.ColumnHeader columnHeader2;
		private System.Windows.Forms.ColumnHeader columnHeader3;
		private System.Windows.Forms.ListView lvArrivalLabels;
		private System.Windows.Forms.CheckBox cbStartNode;
		private System.Windows.Forms.ContextMenu pmenNodes;
		private System.Windows.Forms.MenuItem mniAddNode;
		private System.Windows.Forms.MenuItem mniDeleteNode;
		private System.Windows.Forms.ContextMenu pmenArrivalLabels;
		private System.Windows.Forms.MenuItem menuItem1;
		private System.Windows.Forms.MenuItem menuItem2;
		private System.Windows.Forms.ContextMenu pmenEdges;
		private System.Windows.Forms.MenuItem menuItem3;
		private System.Windows.Forms.MenuItem menuItem4;
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		public TfrmNodes()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.lblLabel = new System.Windows.Forms.ColumnHeader();
			this.pnlLabel = new System.Windows.Forms.Panel();
			this.cbStartNode = new System.Windows.Forms.CheckBox();
			this.lvArrivalLabels = new System.Windows.Forms.ListView();
			this.columnHeader3 = new System.Windows.Forms.ColumnHeader();
			this.panel1 = new System.Windows.Forms.Panel();
			this.panel2 = new System.Windows.Forms.Panel();
			this.cbLabel = new System.Windows.Forms.ComboBox();
			this.cbToNode = new System.Windows.Forms.ComboBox();
			this.label8 = new System.Windows.Forms.Label();
			this.label9 = new System.Windows.Forms.Label();
			this.splitter2 = new System.Windows.Forms.Splitter();
			this.lvEdges = new System.Windows.Forms.ListView();
			this.columnHeader2 = new System.Windows.Forms.ColumnHeader();
			this.btnBrowseFileName = new System.Windows.Forms.Button();
			this.edFileName = new System.Windows.Forms.TextBox();
			this.label4 = new System.Windows.Forms.Label();
			this.lblNodeCode = new System.Windows.Forms.Label();
			this.edDescription = new System.Windows.Forms.TextBox();
			this.edDisplayName = new System.Windows.Forms.TextBox();
			this.label3 = new System.Windows.Forms.Label();
			this.label2 = new System.Windows.Forms.Label();
			this.label1 = new System.Windows.Forms.Label();
			this.odFileName = new System.Windows.Forms.OpenFileDialog();
			this.lvNodes = new System.Windows.Forms.ListView();
			this.columnHeader1 = new System.Windows.Forms.ColumnHeader();
			this.splitter1 = new System.Windows.Forms.Splitter();
			this.pmenNodes = new System.Windows.Forms.ContextMenu();
			this.mniAddNode = new System.Windows.Forms.MenuItem();
			this.mniDeleteNode = new System.Windows.Forms.MenuItem();
			this.pmenArrivalLabels = new System.Windows.Forms.ContextMenu();
			this.menuItem1 = new System.Windows.Forms.MenuItem();
			this.menuItem2 = new System.Windows.Forms.MenuItem();
			this.pmenEdges = new System.Windows.Forms.ContextMenu();
			this.menuItem3 = new System.Windows.Forms.MenuItem();
			this.menuItem4 = new System.Windows.Forms.MenuItem();
			this.pnlLabel.SuspendLayout();
			this.panel1.SuspendLayout();
			this.panel2.SuspendLayout();
			this.SuspendLayout();
			// 
			// lblLabel
			// 
			this.lblLabel.Text = "Label";
			this.lblLabel.Width = 100;
			// 
			// pnlLabel
			// 
			this.pnlLabel.Controls.Add(this.cbStartNode);
			this.pnlLabel.Controls.Add(this.lvArrivalLabels);
			this.pnlLabel.Controls.Add(this.panel1);
			this.pnlLabel.Controls.Add(this.btnBrowseFileName);
			this.pnlLabel.Controls.Add(this.edFileName);
			this.pnlLabel.Controls.Add(this.label4);
			this.pnlLabel.Controls.Add(this.lblNodeCode);
			this.pnlLabel.Controls.Add(this.edDescription);
			this.pnlLabel.Controls.Add(this.edDisplayName);
			this.pnlLabel.Controls.Add(this.label3);
			this.pnlLabel.Controls.Add(this.label2);
			this.pnlLabel.Controls.Add(this.label1);
			this.pnlLabel.Dock = System.Windows.Forms.DockStyle.Fill;
			this.pnlLabel.Location = new System.Drawing.Point(163, 0);
			this.pnlLabel.Name = "pnlLabel";
			this.pnlLabel.Size = new System.Drawing.Size(437, 333);
			this.pnlLabel.TabIndex = 2;
			// 
			// cbStartNode
			// 
			this.cbStartNode.Location = new System.Drawing.Point(8, 40);
			this.cbStartNode.Name = "cbStartNode";
			this.cbStartNode.Size = new System.Drawing.Size(136, 24);
			this.cbStartNode.TabIndex = 2;
			this.cbStartNode.Text = "This is the Start Node";
			this.cbStartNode.CheckedChanged += new System.EventHandler(this.cbStartNode_CheckedChanged);
			// 
			// lvArrivalLabels
			// 
			this.lvArrivalLabels.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.lvArrivalLabels.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
																							  this.columnHeader3});
			this.lvArrivalLabels.ContextMenu = this.pmenArrivalLabels;
			this.lvArrivalLabels.HideSelection = false;
			this.lvArrivalLabels.Location = new System.Drawing.Point(256, 8);
			this.lvArrivalLabels.MultiSelect = false;
			this.lvArrivalLabels.Name = "lvArrivalLabels";
			this.lvArrivalLabels.Size = new System.Drawing.Size(176, 200);
			this.lvArrivalLabels.Sorting = System.Windows.Forms.SortOrder.Ascending;
			this.lvArrivalLabels.TabIndex = 7;
			this.lvArrivalLabels.View = System.Windows.Forms.View.Details;
			this.lvArrivalLabels.SelectedIndexChanged += new System.EventHandler(this.lvArrivalLabels_SelectedIndexChanged);
			// 
			// columnHeader3
			// 
			this.columnHeader3.Text = "Arrival Labels";
			this.columnHeader3.Width = 150;
			// 
			// panel1
			// 
			this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
				| System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right)));
			this.panel1.Controls.Add(this.panel2);
			this.panel1.Controls.Add(this.splitter2);
			this.panel1.Controls.Add(this.lvEdges);
			this.panel1.Location = new System.Drawing.Point(8, 216);
			this.panel1.Name = "panel1";
			this.panel1.Size = new System.Drawing.Size(424, 112);
			this.panel1.TabIndex = 9;
			// 
			// panel2
			// 
			this.panel2.Controls.Add(this.cbLabel);
			this.panel2.Controls.Add(this.cbToNode);
			this.panel2.Controls.Add(this.label8);
			this.panel2.Controls.Add(this.label9);
			this.panel2.Dock = System.Windows.Forms.DockStyle.Fill;
			this.panel2.Location = new System.Drawing.Point(163, 0);
			this.panel2.Name = "panel2";
			this.panel2.Size = new System.Drawing.Size(261, 112);
			this.panel2.TabIndex = 7;
			// 
			// cbLabel
			// 
			this.cbLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right)));
			this.cbLabel.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
			this.cbLabel.Location = new System.Drawing.Point(72, 40);
			this.cbLabel.Name = "cbLabel";
			this.cbLabel.Size = new System.Drawing.Size(184, 21);
			this.cbLabel.TabIndex = 10;
			this.cbLabel.SelectedIndexChanged += new System.EventHandler(this.cbLabel_SelectedIndexChanged);
			// 
			// cbToNode
			// 
			this.cbToNode.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right)));
			this.cbToNode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
			this.cbToNode.Location = new System.Drawing.Point(72, 8);
			this.cbToNode.Name = "cbToNode";
			this.cbToNode.Size = new System.Drawing.Size(184, 21);
			this.cbToNode.TabIndex = 9;
			this.cbToNode.SelectedIndexChanged += new System.EventHandler(this.cbToNode_SelectedIndexChanged);
			// 
			// label8
			// 
			this.label8.Location = new System.Drawing.Point(8, 40);
			this.label8.Name = "label8";
			this.label8.Size = new System.Drawing.Size(48, 16);
			this.label8.TabIndex = 1;
			this.label8.Text = "Label:";
			// 
			// label9
			// 
			this.label9.Location = new System.Drawing.Point(8, 8);
			this.label9.Name = "label9";
			this.label9.Size = new System.Drawing.Size(56, 16);
			this.label9.TabIndex = 0;
			this.label9.Text = "To Node:";
			// 
			// splitter2
			// 
			this.splitter2.Location = new System.Drawing.Point(160, 0);
			this.splitter2.Name = "splitter2";
			this.splitter2.Size = new System.Drawing.Size(3, 112);
			this.splitter2.TabIndex = 6;
			this.splitter2.TabStop = false;
			// 
			// lvEdges
			// 
			this.lvEdges.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
																					  this.columnHeader2});
			this.lvEdges.ContextMenu = this.pmenEdges;
			this.lvEdges.Dock = System.Windows.Forms.DockStyle.Left;
			this.lvEdges.HideSelection = false;
			this.lvEdges.Location = new System.Drawing.Point(0, 0);
			this.lvEdges.MultiSelect = false;
			this.lvEdges.Name = "lvEdges";
			this.lvEdges.Size = new System.Drawing.Size(160, 112);
			this.lvEdges.TabIndex = 8;
			this.lvEdges.View = System.Windows.Forms.View.Details;
			this.lvEdges.Resize += new System.EventHandler(this.lvEdges_Resize);
			this.lvEdges.SelectedIndexChanged += new System.EventHandler(this.lvEdges_SelectedIndexChanged);
			// 
			// columnHeader2
			// 
			this.columnHeader2.Text = "Edges";
			this.columnHeader2.Width = 150;
			// 
			// btnBrowseFileName
			// 
			this.btnBrowseFileName.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.btnBrowseFileName.Location = new System.Drawing.Point(224, 184);
			this.btnBrowseFileName.Name = "btnBrowseFileName";
			this.btnBrowseFileName.Size = new System.Drawing.Size(24, 23);
			this.btnBrowseFileName.TabIndex = 6;
			this.btnBrowseFileName.Text = "...";
			this.btnBrowseFileName.Click += new System.EventHandler(this.btnBrowseFileName_Click);
			// 
			// edFileName
			// 
			this.edFileName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right)));
			this.edFileName.Location = new System.Drawing.Point(64, 184);
			this.edFileName.Name = "edFileName";
			this.edFileName.Size = new System.Drawing.Size(152, 20);
			this.edFileName.TabIndex = 5;
			this.edFileName.Text = "";
			this.edFileName.TextChanged += new System.EventHandler(this.edFileName_TextChanged);
			// 
			// label4
			// 
			this.label4.Location = new System.Drawing.Point(8, 184);
			this.label4.Name = "label4";
			this.label4.Size = new System.Drawing.Size(56, 23);
			this.label4.TabIndex = 6;
			this.label4.Text = "FileName";
			// 
			// lblNodeCode
			// 
			this.lblNodeCode.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right)));
			this.lblNodeCode.Location = new System.Drawing.Point(64, 16);
			this.lblNodeCode.Name = "lblNodeCode";
			this.lblNodeCode.Size = new System.Drawing.Size(184, 23);
			this.lblNodeCode.TabIndex = 5;
			// 
			// edDescription
			// 
			this.edDescription.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right)));
			this.edDescription.Location = new System.Drawing.Point(8, 112);
			this.edDescription.Multiline = true;
			this.edDescription.Name = "edDescription";
			this.edDescription.Size = new System.Drawing.Size(240, 64);
			this.edDescription.TabIndex = 4;
			this.edDescription.Text = "";
			this.edDescription.TextChanged += new System.EventHandler(this.edDescription_TextChanged);
			// 
			// edDisplayName
			// 
			this.edDisplayName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right)));
			this.edDisplayName.Location = new System.Drawing.Point(64, 64);
			this.edDisplayName.Name = "edDisplayName";
			this.edDisplayName.Size = new System.Drawing.Size(184, 20);
			this.edDisplayName.TabIndex = 3;
			this.edDisplayName.Text = "";
			this.edDisplayName.Validating += new System.ComponentModel.CancelEventHandler(this.edDisplayName_Validating);
			this.edDisplayName.TextChanged += new System.EventHandler(this.edDisplayName_TextChanged);
			// 
			// label3
			// 
			this.label3.Location = new System.Drawing.Point(8, 88);
			this.label3.Name = "label3";
			this.label3.TabIndex = 2;
			this.label3.Text = "Description";
			// 
			// label2
			// 
			this.label2.Location = new System.Drawing.Point(8, 64);
			this.label2.Name = "label2";
			this.label2.Size = new System.Drawing.Size(48, 23);
			this.label2.TabIndex = 1;
			this.label2.Text = "Name";
			// 
			// label1
			// 
			this.label1.Location = new System.Drawing.Point(8, 16);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(48, 23);
			this.label1.TabIndex = 0;
			this.label1.Text = "Code";
			// 
			// odFileName
			// 
			this.odFileName.DefaultExt = "wav";
			this.odFileName.Filter = "Wav Files|*.wav|All Files|*.*";
			// 
			// lvNodes
			// 
			this.lvNodes.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
																					  this.columnHeader1});
			this.lvNodes.ContextMenu = this.pmenNodes;
			this.lvNodes.Dock = System.Windows.Forms.DockStyle.Left;
			this.lvNodes.HideSelection = false;
			this.lvNodes.Location = new System.Drawing.Point(0, 0);
			this.lvNodes.MultiSelect = false;
			this.lvNodes.Name = "lvNodes";
			this.lvNodes.Size = new System.Drawing.Size(160, 333);
			this.lvNodes.TabIndex = 1;
			this.lvNodes.View = System.Windows.Forms.View.Details;
			this.lvNodes.Resize += new System.EventHandler(this.lvNodes_Resize);
			this.lvNodes.SelectedIndexChanged += new System.EventHandler(this.lvNodes_SelectedIndexChanged);
			// 
			// columnHeader1
			// 
			this.columnHeader1.Text = "Node";
			this.columnHeader1.Width = 150;
			// 
			// splitter1
			// 
			this.splitter1.Location = new System.Drawing.Point(160, 0);
			this.splitter1.Name = "splitter1";
			this.splitter1.Size = new System.Drawing.Size(3, 333);
			this.splitter1.TabIndex = 5;
			this.splitter1.TabStop = false;
			// 
			// pmenNodes
			// 
			this.pmenNodes.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																					  this.mniAddNode,
																					  this.mniDeleteNode});
			this.pmenNodes.Popup += new System.EventHandler(this.pmenNodes_Popup);
			// 
			// mniAddNode
			// 
			this.mniAddNode.Index = 0;
			this.mniAddNode.Text = "Add Node";
			// 
			// mniDeleteNode
			// 
			this.mniDeleteNode.Index = 1;
			this.mniDeleteNode.Text = "Delete Node";
			// 
			// pmenArrivalLabels
			// 
			this.pmenArrivalLabels.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																							  this.menuItem1,
																							  this.menuItem2});
			this.pmenArrivalLabels.Popup += new System.EventHandler(this.pmenArrivalLabels_Popup);
			// 
			// menuItem1
			// 
			this.menuItem1.Index = 0;
			this.menuItem1.Text = "Add Arrival Label";
			// 
			// menuItem2
			// 
			this.menuItem2.Index = 1;
			this.menuItem2.Text = "Delete Arrival Label";
			// 
			// pmenEdges
			// 
			this.pmenEdges.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																					  this.menuItem3,
																					  this.menuItem4});
			this.pmenEdges.Popup += new System.EventHandler(this.pmenEdges_Popup);
			// 
			// menuItem3
			// 
			this.menuItem3.Index = 0;
			this.menuItem3.Text = "Add Edge";
			// 
			// menuItem4
			// 
			this.menuItem4.Index = 1;
			this.menuItem4.Text = "Delete Edge";
			// 
			// TfrmNodes
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(600, 333);
			this.Controls.Add(this.pnlLabel);
			this.Controls.Add(this.splitter1);
			this.Controls.Add(this.lvNodes);
			this.Name = "TfrmNodes";
			this.Text = "Nodes";
			this.Load += new System.EventHandler(this.TfrmNodes_Load);
			this.Closed += new System.EventHandler(this.TfrmNodes_Closed);
			this.pnlLabel.ResumeLayout(false);
			this.panel1.ResumeLayout(false);
			this.panel2.ResumeLayout(false);
			this.ResumeLayout(false);

		}
		#endregion

		private int fIsUpdating = 0;
		private ArrayList fToNodes = new ArrayList();
		private ArrayList fLabels = new ArrayList();

		public TAleaGraph AleaGraph = null;
		public TSignalChangeDelegate SignalChangeDelegate = null;
	
		private void edDisplayName_TextChanged(object sender, System.EventArgs e)
		{
			if ((fIsUpdating == 0) && SelectedNode != null)
			{
				SelectedNode.DisplayName = edDisplayName.Text;
				SignalChangeDelegate();
				UpdateCaptions();
			}
		}

		public TNode SelectedNode
		{
			get
			{
				TNode retval = null;
				if (lvNodes.SelectedItems.Count > 0)
					retval = lvNodes.SelectedItems[0].Tag as TNode;
				return retval;
			}
		}

		public TEdge SelectedEdge
		{
			get
			{
				TEdge retval = null;
				if (lvEdges.SelectedItems.Count > 0)
					retval = lvEdges.SelectedItems[0].Tag as TEdge;
				return retval;
			}
		}

		public TLabel SelectedArrivalLabel
		{
			get
			{
				TLabel retval = null;
				if (lvArrivalLabels.SelectedItems.Count > 0)
					retval = lvArrivalLabels.SelectedItems[0].Tag as TLabel;
				return retval;
			}
		}

		public  void UpdateControls()
		{
			fIsUpdating++;
			try
			{
				// save selection for later restoration
				TNode SaveNode = SelectedNode;

				lvNodes.BeginUpdate();
				try
				{
					lvNodes.Items.Clear();

					if (AleaGraph != null)
					{
						foreach(TNode Node in AleaGraph.Nodes)
						{
							ListViewItem lListViewItem = new ListViewItem();

							lListViewItem.Text = ""; // call updatecaptions() later
							lListViewItem.Tag = Node;
							lvNodes.Items.Add(lListViewItem);

							if (SaveNode == Node)
								lListViewItem.Selected = true;
						}
					}

					if ((lvNodes.Items.Count > 0) && (lvNodes.SelectedItems.Count == 0))
					{
						lvNodes.Items[0].Selected = true;
					}

					UpdateCaptions();
				}
				finally
				{
					lvNodes.EndUpdate();
				}
			}
			finally
			{
				fIsUpdating--;
			}
		}

		private void UpdateCaptions()
		{
			foreach(ListViewItem lvi in lvNodes.Items)
			{
				if (lvi.Tag is TNode)
				{
					TNode Node = lvi.Tag as TNode;
					if (AleaGraph.StartNode == Node)
						lvi.Text = "* ";
					else
						lvi.Text = "";
					lvi.Text += Node.DisplayName;
				}
			}
		}

		private void UpdateDetail()
		{
			fIsUpdating ++;
			try
			{
				cbToNode.Items.Clear();
				cbToNode.Text = "";
				fToNodes.Clear();
				cbLabel.Items.Clear();
				cbLabel.Text = "";
				fLabels.Clear();

				if (SelectedNode != null)
				{
					cbStartNode.Checked = AleaGraph.StartNode == SelectedNode;

					lblNodeCode.Text = SelectedNode.NodeCode;
					edDisplayName.Text = SelectedNode.DisplayName;
					edDescription.Text = SelectedNode.Description;
					edFileName.Text = SelectedNode.FileName;

					lvArrivalLabels.Items.Clear();
					foreach (TLabel ArrivalLabel in SelectedNode.ArrivalLabels)
					{
						ListViewItem lvi = new ListViewItem();
						lvi.Text = ArrivalLabel.DisplayName;
						lvi.Tag = ArrivalLabel;
						lvArrivalLabels.Items.Add(lvi);
					}

					UpdateEdgesControls();
				}
			}
			finally
			{
				fIsUpdating--;
			}
		}

		private void UpdateEdgesControls()
		{
			if (SelectedNode != null)
			{
				fIsUpdating++;
				try
				{
					// save selection for later restoration
					TEdge SaveEdge = SelectedEdge;

					lvEdges.BeginUpdate();
					try
					{
						lvEdges.Items.Clear();

						if (AleaGraph != null)
						{
							foreach(TEdge Edge in SelectedNode.Edges)
							{
								ListViewItem lListViewItem = new ListViewItem();

								lListViewItem.Text = ""; // call updatecaptions() later
								lListViewItem.Tag = Edge;
								lvEdges.Items.Add(lListViewItem);

								if (SaveEdge == Edge)
									lListViewItem.Selected = true;
							}
						}

						if ((lvEdges.Items.Count > 0) && (lvEdges.SelectedItems.Count == 0))
						{
							lvEdges.Items[0].Selected = true;
						}

						UpdateEdgesCaptions();
					}
					finally
					{
						lvEdges.EndUpdate();
					}
				}
				finally
				{
					fIsUpdating--;
				}
			}
		}

		private void UpdateEdgesCaptions()
		{
			foreach(ListViewItem lvi in lvEdges.Items)
			{
				if (lvi.Tag is TEdge)
				{
					TEdge Edge = lvi.Tag as TEdge;
					if (Edge.Label != null)
						lvi.Text = Edge.Label.DisplayName + ": ";
					else
						lvi.Text = "";
					if (Edge.ToNode != null)
						lvi.Text += "To " + Edge.ToNode.DisplayName;
					else
						lvi.Text += "END";
				}
			}
		}

		private void UpdateEdgesDetail()
		{
			fIsUpdating ++;
			try
			{
				if (SelectedEdge != null)
				{
					// now update the combo box lists
					cbToNode.Items.Clear();
					fToNodes.Clear();
					cbToNode.Items.Add("<None>");
					fToNodes.Add(null);
					foreach (TNode Node in AleaGraph.Nodes)
					{
						cbToNode.Items.Add(Node.DisplayName);
						fToNodes.Add(Node);
					}

					// now update the combo box lists
					cbLabel.Items.Clear();
					fLabels.Clear();
					cbLabel.Items.Add("<None>");
					fLabels.Add(null);
					foreach (TLabel Label in AleaGraph.Labels)
					{
						cbLabel.Items.Add(Label.DisplayName);
						fLabels.Add(Label);
					}

					// now update selection in the combos
					int ix;

					ix = 0;
					cbToNode.SelectedIndex = -1;
					foreach (TNode Node in fToNodes)
					{
						if (SelectedEdge.ToNode == Node)
						{
							cbToNode.SelectedIndex = ix;
						}
						ix++;
					}

					ix = 0;
					cbLabel.SelectedIndex = -1;
					foreach (TLabel Label in fLabels)
					{
						if (SelectedEdge.Label == Label)
						{
							cbLabel.SelectedIndex = ix;
						}
						ix++;
					}
				}
			}
			finally
			{
				fIsUpdating--;
			}
		}

		private void TfrmNodes_Load(object sender, System.EventArgs e)
		{
			SetupEnablements();

			UpdateControls();
		}

		private void lvNodes_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			UpdateDetail();
			SignalChangeDelegate();
		}

		private void edDisplayName_Validating(object sender, System.ComponentModel.CancelEventArgs e)
		{
			e.Cancel = edDisplayName.Text.Trim().Length == 0;
		}

		private void edDescription_TextChanged(object sender, System.EventArgs e)
		{
			if ((fIsUpdating == 0) && SelectedNode != null)
			{
				SelectedNode.Description = edDescription.Text;
				SignalChangeDelegate();
			}
		}
		
		public void DoAddNode()
		{
			TNode lNode = new TNode("New Node", "", "");
			AleaGraph.Nodes.Add(lNode);
			UpdateControls();
			SignalChangeDelegate();
		}

		public void DoDeleteNode()
		{
			if (SelectedNode != null)
			{
				if (MessageBox.Show("Are you sure?", "Delete Node", MessageBoxButtons.YesNo) == DialogResult.Yes)
				{
					AleaGraph.Nodes.Remove(SelectedNode);
					UpdateControls();
					SignalChangeDelegate();
				}
			}
		}

		private void btnBrowseFileName_Click(object sender, System.EventArgs e)
		{
			odFileName.FileName = edFileName.Text;
			if (odFileName.ShowDialog() == DialogResult.OK)
				edFileName.Text = odFileName.FileName;
		}

		private void edFileName_TextChanged(object sender, System.EventArgs e)
		{
			if ((fIsUpdating == 0) && SelectedNode != null)
			{
				SelectedNode.FileName = edFileName.Text;
				SignalChangeDelegate();
			}
		}

		private void lvEdges_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			UpdateEdgesDetail();
		}

		private void cbToNode_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			if ((fIsUpdating == 0) && SelectedEdge != null)
			{
				SelectedEdge.ToNode = fToNodes[cbToNode.SelectedIndex] as TNode;
				SignalChangeDelegate();
				UpdateEdgesCaptions();
			}
		}

		private void cbLabel_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			if ((fIsUpdating == 0) && SelectedEdge != null)
			{
				SelectedEdge.Label = fLabels[cbLabel.SelectedIndex] as TLabel;
				SignalChangeDelegate();
				UpdateEdgesCaptions();
			}
		}

		public void DoAddEdge()
		{
			TEdge lEdge = new TEdge(SelectedNode, null, null, true);
			SelectedNode.Edges.Add(lEdge);
			SignalChangeDelegate();
			UpdateEdgesControls();
		}

		public void DoDeleteEdge()
		{
			if (SelectedEdge != null)
			{
				if (MessageBox.Show("Are you sure?", "Delete Edge", MessageBoxButtons.YesNo) == DialogResult.Yes)
				{
					SelectedNode.Edges.Remove(SelectedEdge);
					SignalChangeDelegate();
					UpdateEdgesControls();
				}
			}
		}

		public void DoAddArrivalLabel()
		{
			TLabel lArrivalLabel = TfrmChooseLabel.ChooseLabel(AleaGraph.Labels);

			if (lArrivalLabel != null && !SelectedNode.ArrivalLabels.Contains(lArrivalLabel))
			{
				SelectedNode.ArrivalLabels.Add(lArrivalLabel);
				SignalChangeDelegate();
				UpdateControls();
			}
		}

		public void DoDeleteArrivalLabel()
		{
			if (SelectedArrivalLabel != null)
			{
				if (MessageBox.Show("Are you sure?", "Delete Arrival Label", MessageBoxButtons.YesNo) == DialogResult.Yes)
				{
					SelectedNode.ArrivalLabels.Remove(SelectedArrivalLabel);
					UpdateControls();
					SignalChangeDelegate();
				}
			}
		}

		private void lvEdges_Resize(object sender, System.EventArgs e)
		{
			lvEdges.Columns[0].Width = lvEdges.ClientRectangle.Width;
		}

		private void lvNodes_Resize(object sender, System.EventArgs e)
		{
			lvNodes.Columns[0].Width = lvNodes.ClientRectangle.Width;
		}

		private void lvArrivalLabels_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			SignalChangeDelegate();
		}

		private void cbStartNode_CheckedChanged(object sender, System.EventArgs e)
		{
			if ((fIsUpdating == 0) && SelectedNode != null)
			{
				if (cbStartNode.Checked)
					AleaGraph.StartNode = SelectedNode;
				else
					AleaGraph.StartNode = null;
				SignalChangeDelegate();
				UpdateCaptions();
			}
		}

		private void TfrmNodes_Closed(object sender, System.EventArgs e)
		{
			TeardownEnablements();
		}

		public void SetupEnablements()
		{
			EnablementManager.SetDelegates(
				"Add Node", 
				new TEnablementCheckDelegate(AddNodeEnablementCheck),
				new TEnablementExecuteDelegate(DoAddNode)
				);

			EnablementManager.SetDelegates(
				"Delete Node", 
				new TEnablementCheckDelegate(DeleteNodeEnablementCheck),
				new TEnablementExecuteDelegate(DoDeleteNode)
				);

			EnablementManager.SetDelegates(
				"Add Arrival Label", 
				new TEnablementCheckDelegate(AddArrivalLabelEnablementCheck),
				new TEnablementExecuteDelegate(DoAddArrivalLabel)
				);

			EnablementManager.SetDelegates(
				"Delete Arrival Label", 
				new TEnablementCheckDelegate(DeleteArrivalLabelEnablementCheck),
				new TEnablementExecuteDelegate(DoDeleteArrivalLabel)
				);

			EnablementManager.SetDelegates(
				"Add Edge", 
				new TEnablementCheckDelegate(AddEdgeEnablementCheck),
				new TEnablementExecuteDelegate(DoAddEdge)
				);

			EnablementManager.SetDelegates(
				"Delete Edge", 
				new TEnablementCheckDelegate(DeleteEdgeEnablementCheck),
				new TEnablementExecuteDelegate(DoDeleteEdge)
				);

			EnablementManager.AddContextMenu(pmenNodes);
			EnablementManager.AddContextMenu(pmenArrivalLabels);
			EnablementManager.AddContextMenu(pmenEdges);
		}

		public void TeardownEnablements()
		{
			EnablementManager.RemoveContextMenu(pmenNodes);
			EnablementManager.RemoveContextMenu(pmenArrivalLabels);
			EnablementManager.RemoveContextMenu(pmenEdges);

			EnablementManager.ClearDelegates("Add Node");
			EnablementManager.ClearDelegates("Delete Node");
			EnablementManager.ClearDelegates("Add Arrival Label");
			EnablementManager.ClearDelegates("Delete Arrival Label");
			EnablementManager.ClearDelegates("Add Edge");
			EnablementManager.ClearDelegates("Delete Edge");
		}

		private void AddNodeEnablementCheck(ref bool aIsEnabled)
		{
			aIsEnabled = true;
		}

		private void DeleteNodeEnablementCheck(ref bool aIsEnabled)
		{
			aIsEnabled = SelectedNode != null;
		}

		private void AddArrivalLabelEnablementCheck(ref bool aIsEnabled)
		{
			aIsEnabled = SelectedNode != null;;
		}

		private void DeleteArrivalLabelEnablementCheck(ref bool aIsEnabled)
		{
			aIsEnabled = SelectedArrivalLabel != null;
		}

		private void AddEdgeEnablementCheck(ref bool aIsEnabled)
		{
			aIsEnabled = SelectedNode != null;
		}

		private void DeleteEdgeEnablementCheck(ref bool aIsEnabled)
		{
			aIsEnabled = SelectedEdge != null;
		}

		private void pmenNodes_Popup(object sender, System.EventArgs e)
		{
			SignalChangeDelegate();
		}

		private void pmenArrivalLabels_Popup(object sender, System.EventArgs e)
		{
			SignalChangeDelegate();
		}

		private void pmenEdges_Popup(object sender, System.EventArgs e)
		{
			SignalChangeDelegate();
		}
	}
}

